from datetime import datetime
import akshare as ak
from manger import scheduler
from flask import Blueprint, request, current_app
from views import kpl_tool, tld_tool
from dao.seleted_stock import SeletedStockSchema, SeletedStock
from dao.candidate_stock import CandidateStockSchema, CandidateStock
from dao import PositonStock,PositonStockSchema
from dao.user import User, UserSchema
from manger import db
from concurrent.futures import ThreadPoolExecutor
import concurrent.futures
from views import redis_tool
from views import notice_tool
from sqlalchemy import and_, desc
from dao.trading_calendar import TradingCalendar,TradingCalendarSchema

kpl = Blueprint('kpl', __name__)

# 更新精选股票
@kpl.route('/updatetoken')
def update_token_tld():
    return tld_tool.get_tld_token()

# 更新精选股票
@kpl.route('/updateseleted')
def update_seleted_kpl():
    last_date = redis_tool.get_last_date()[0]
    date = request.args.get('date', last_date)
    return upadte_kpl_selected_stocks(date)

@kpl.route('/logincount')
def get_login_count():
    count =redis_tool.get_login_count()
    return {'code': 1, 'messge': '获取成功','data':{'count':count}}

# 更新候选股票
@kpl.route('/updatecandidate')
def update_candidate_kpl():

    last_date = redis_tool.get_last_date()[0]
    date = request.args.get('date', last_date)
    return upadte_kpl_candidate_stocks(date)

# 更新所有股票
@kpl.route('/updateallstocks')
def update_all_stocks():
    last_date = redis_tool.get_last_date()[0]
    try:
        date = request.args.get('date', last_date)
    except Exception as e:
        date = last_date
    print('====',date)
    tld_tool.get_tld_token()
    update_redis_last()
    update_redis_top5_concept()
    upadte_kpl_selected_stocks(date)
    upadte_kpl_candidate_stocks(date)
    deleted_all_stocks()
    return {'code': 1, 'messge': '更新成功'}



@kpl.route('/updateredyellow')
def update_redyellow():
    return upadte_kpl_red_yellow_stocks()

@kpl.route('/getmontiorlist')
def get_montior_list():
    token = redis_tool.get_tld_token()
    res = tld_tool.get_tld_montior_info(token)
    if res['code'] == 200:
        return {'code': 1, 'message': res['msg'], 'data': res['data']}
    elif res['code'] == 20001 or res['code'] == 20002:
        tld_tool.get_tld_token()
        return get_montior_list()
    else:
        return {'code': res['code'], 'message': res['msg']}

@kpl.route('/kplmontiorstocks')
def get_kplmontiorstocks_list():
    token = redis_tool.get_tld_token()
    # 获取监控股票池
    res = tld_tool.get_tld_montior_info(token)
    if  res['code'] == 200:
        montior_stocks = res['data']['datas']
        candidate_stocks = CandidateStock.query.all()
        us = CandidateStockSchema()
        stock_dic = us.dump(candidate_stocks, many=True)
        gl_stocks = []
        for stock in montior_stocks:
            candidate_stock = list(filter(lambda x: x['Name'] == stock['name'], stock_dic))
            if candidate_stock:
                stock['candidate_stock'] = candidate_stock[0]
            gl_stocks.append(stock)
        return {'code': 1, 'messge': res['msg'],
                'data': {'stocks': gl_stocks}}
    elif res['code'] == 20001 or res['code'] == 20002:
        tld_tool.get_tld_token()
        return get_kplmontiorstocks_list()
    else:
        return {'code': res['code'], 'messge': res['msg']}

# 获取屠龙刀候精选股票
@kpl.route('/getseleted')
def getseleted_stocks():
    last_date = redis_tool.get_last_date()[0]
    date = request.args.get('date', last_date)
    last_date_time = datetime.strptime(date, '%Y-%m-%d')
    stocks = SeletedStock.query.filter(SeletedStock.date >=last_date_time ).all()
    us = SeletedStockSchema()
    stock_dic = us.dump(stocks, many=True)
    cs = CandidateStockSchema()
    for stock in stock_dic:
        candidate_stock = CandidateStock.query.filter(CandidateStock.Code == stock['code']).first()
        stock['candidate_stock'] = cs.dump(candidate_stock)
    return {'code': 1, 'messge': '获取精选股票池成功', 'data': stock_dic}

# 获取屠龙刀候选池股票
@kpl.route('/getcandidate')
def get_candidate_stocks():
    last_date = redis_tool.get_last_date()[0]
    date = request.args.get('date', last_date)
    last_date_time = datetime.strptime(date, '%Y-%m-%d')
    stocks = CandidateStock.query.filter(CandidateStock.Date >= last_date_time).all()
    us = CandidateStockSchema()
    stock_dic = us.dump(stocks, many=True)
    return {'code': 1, 'messge': '获取候选股票池成功', 'data': stock_dic}

# 获取屠龙刀候选池股票
@kpl.route('/deletedall')
def deleted_all_stocks():
    last_date = redis_tool.get_last_date()[1]
    try:
        date = request.args.get('date', last_date)
    except Exception as e:
        date = last_date
    last_date_time = datetime.strptime(date, '%Y-%m-%d')
    c_stocks = CandidateStock.query.filter(CandidateStock.Date < last_date_time).delete()
    s_stocks = SeletedStock.query.filter(SeletedStock.date < last_date_time).delete()
    db.session.commit()
    return {'code': 1, 'messge': '删除成功'}
@kpl.route('/getcost/<cost>')
def get_cost_stocks(cost):
    if cost == '0':
        stocks = CandidateStock.query.filter(and_(CandidateStock.isCover15 == 1,CandidateStock.NowCost15 > 0)).order_by(CandidateStock.cover15Time.desc()).all()
    else:
        stocks = CandidateStock.query.filter(and_(CandidateStock.isCover30 == 1,CandidateStock.NowCost30 > 0)).order_by(CandidateStock.cover30Time.desc()).all()
    us = CandidateStockSchema()
    stock_dic = us.dump(stocks, many=True)
    return {'code': 1, 'messge': '获取候选股票池成功', 'data': stock_dic}

# 获取屠龙刀候选池股票codeStr
@kpl.route('/candidatecodes')
def get_candidate_codes():
    codes = redis_tool.get_candidate_codes()
    return {'code': 1, 'messge': '获取候选股票池代码成功', 'data': codes}
# 获取屠龙刀精选股票codeStr
@kpl.route('/selectedcodes')
def get_selected_codes():
    codes = redis_tool.get_seleted_codes()
    return {'code': 1, 'messge': '获取精选股票池代码成功', 'data': codes}

# 获取屠龙刀所有股票codeStr
@kpl.route('/allcodes')
def get_all_codes():
    candidate_stocks = CandidateStock.query.all()
    candidate_codes = list(map(lambda x: x.Code, candidate_stocks))

    selected_stocks = SeletedStock.query.all()
    selected_codes = list(map(lambda x: x.code, selected_stocks))

    position_stocks = PositonStock.query.all()
    position_codes = list(map(lambda x: x.code, position_stocks))
    all_codes = candidate_codes + selected_codes + position_codes
    all_set = set(all_codes)
    all_str = ','.join(all_set)
    return {'code': 1, 'messge': '获取候选股票池代码成功', 'data': all_str}

# 获取屠龙刀精选跟候选股票
@kpl.route('/getstocks')
def get_stocks():
    seleted_stocks = SeletedStock.query.all()
    seleted_us = SeletedStockSchema()
    seleted_stock_dic = seleted_us.dump(seleted_stocks, many=True)
    candidate_stocks = CandidateStock.query.all()
    candidate_us = CandidateStockSchema()
    candidate_stock_dic = candidate_us.dump(candidate_stocks, many=True)
    return {'code': 1, 'messge': '获取候选股票池成功',
            'data': {'seleted': seleted_stock_dic,
                     'candidate': candidate_stock_dic}}

# 获取屠龙刀热点概念列表
@kpl.route('/hotgl')
def hotgl():
    token = redis_tool.get_tld_token()
    # 获取候选池
    res = tld_tool.get_tld_montior_stocks(token)
    if res['code'] == 200:
        return {'code': 1, 'messge': '获取热点概念成功',
                'data': {'datas': res['data']['index']}}
    elif res['code'] == 20001 or res['code'] == 20002:
        tld_tool.get_tld_token()
        return hotgl()

    else:
        return {'code': res['code'], 'messge': res['msg']}

# 获取屠龙刀最后几天的日期
@kpl.route('/last')
def get_last():
    token = redis_tool.get_tld_token()
    res = tld_tool.get_last(token)
    if res['code']:
        return {'code': 1, 'messge': res['msg'],
                'data': res['data']}
    elif res['code'] == 20001 or res['code'] == 20002:
        tld_tool.get_tld_token()
        return get_last()
    else:
        return {'code': res['code'], 'messge': res['msg']}


@kpl.route('/updatelast_redis')
def update_redis_last():
    token = redis_tool.get_tld_token()
    res = tld_tool.get_last(token)
    if res['code'] == 200:
        last_dates = res['data']['last_dates']
        if len(last_dates) > 0:
            last_dates_str = ','.join(last_dates)
            redis_tool.set_last_date(last_dates_str)
        return {'code': 1, 'messge': res['msg'],
                'data': last_dates}
    elif res['code'] == 20001 or res['code'] == 20002:
        tld_tool.get_tld_token()
        return update_redis_last()
    else:
        return {'code': res['code'], 'messge': res['msg']}


# 获取最后一天的日志
@kpl.route('/lastday')
def get_redis_last_day():
    last_dates = redis_tool.get_last_date()
    if len(last_dates) > 0:
        return {'code': 1, 'messge': '获取last_dates成功',
                'data': last_dates[0]}
    else:
        return {'code': 0, 'messge': '获取last_dates失败'}


# 获取最后几天的日志
@kpl.route('/getlastdates')
def get_redis_last():
    last_dates = redis_tool.get_last_date()
    if len(last_dates) > 0:
        return {'code': 1, 'messge': '获取last_dates成功',
                'data': last_dates}
    else:
        return {'code': 0, 'messge': '获取last_dates失败'}



@kpl.route('/update_top5_concept')
def update_redis_top5_concept():
    token = redis_tool.get_tld_token()
    res = tld_tool.get_tld_top5_concept(token)
    if res['code'] == 200:
        hots = []
        last_dates = res['data']['datas']
        for key in last_dates:
            vlues = last_dates[key]
            print(vlues)
            hots.extend(vlues)
        hot_sets = set(hots)
        hots_str = ','.join(hot_sets)
        print(hots_str)
        redis_tool.set_top5_concept(hots_str)
        return {'code': 1, 'messge': res['msg'],
                'data': hots_str}
    elif res['code'] == 20001 or res['code'] == 20002:
        tld_tool.get_tld_token()
        return update_redis_top5_concept()
    else:
        return {'code': res['code'], 'messge': res['msg']}

@kpl.route('/gettop5_concept')
def get_top5_concept():
    last_dates = redis_tool.get_top5_concept()
    if len(last_dates) > 0:
        return {'code': 1, 'messge': '获取top5_concept成功',
                'data': last_dates}
    else:
        return {'code': 0, 'messge': '获取top5_concept失败'}


# 根据开盘啦概念排行榜获取符合条件的个股
@kpl.route('/glstocks/<glName>')
def get_glstocks(glName):
    if len(glName) == 0:
        return {'code': 0, 'messge': f'获取{glName}的股票失败',
                'data': {}}
    token = redis_tool.get_tld_token()

    # 获取候选池
    res = tld_tool.get_tld_montior_stocks(token)
    if res['code'] == 200:
        candidate_stocks = res['data']['datas']
        gl_stocks = []
        # seleted_codes = redis_tool.get_seleted_codes()
        for stock in candidate_stocks:
            candidate_stock = CandidateStock.query.filter(CandidateStock.Name == stock['Name']).first()
            if candidate_stock:
                if glName in candidate_stock.kplTopics:
                    stock['kplTopics'] = candidate_stock.kplTopics
                    gl_stocks.append(candidate_stock)
                candidate_stock.diff = stock['Diff']
                db.session.commit()
        us = CandidateStockSchema()
        stock_dic = us.dump(gl_stocks, many=True)
        return {'code': 1, 'messge': res['msg'],
                'data': {'stocks': stock_dic}}
    elif res['code'] == 20001 or res['code'] == 20002:
        tld_tool.get_tld_token()
        return get_glstocks(glName)
    else:
        return {'code': res['code'], 'messge': res['msg']}

# 根据概念获取屠龙刀到达条件的个股
@kpl.route('/montiorstocks/<glName>')
def get_montiorstocks(glName):
    if len(glName) == 0:
        return {'code': 0, 'messge': f'获取{glName}的股票失败',
                'data': {}}
    token = redis_tool.get_tld_token()
    # 获取监控股票池
    # candidate_res = tld_tool.get_tld_montior_stocks(token)
    res = tld_tool.get_tld_montior_info(token)

    if  res['code'] == 200:
        montior_stocks = res['data']['datas']
        # candidate_stocks = candidate_res['data']['datas']
        print(res)
        gl_stocks = []
        for stock in montior_stocks:
            montior_sql_stock = CandidateStock.query.filter(CandidateStock.Name == stock['name']).first()
            ms = CandidateStockSchema()
            if montior_sql_stock:
                if glName in montior_sql_stock.kplTopics:
                    stock['kplTopics'] = montior_sql_stock.kplTopics
                    # 赋值
                    # candidate_stock = list(filter(lambda x: x['Name'] == stock['name'], montior_sql_stock))
                    stock['candidate_stock'] = ms.dump(montior_sql_stock)
                    gl_stocks.append(stock)

        return {'code': 1, 'messge': res['msg'],
                'data': {'stocks': gl_stocks}}
    elif res['code'] == 20001 or res['code'] == 20002:
        tld_tool.get_tld_token()
        return get_montiorstocks(glName)
    else:
        return {'code': res['code'], 'messge': res['msg']}

# 更新精选股票
def upadte_kpl_selected_stocks(date):
    token = redis_tool.get_tld_token()
    # 获取精选
    res = tld_tool.get_tld_selected_stocks(token, date)
    if res['code'] == 200:
        selected_stocks = res['data']['datas']
        sorted_selected_stocks = sorted(selected_stocks, key=lambda x: x['score'], reverse=True)
        if len(selected_stocks) != 0:
            selected_stock_codes = list(map(lambda x: x['code'], sorted_selected_stocks))
            seleted_codes = ','.join(selected_stock_codes)
            redis_tool.set_seleted_codes(seleted_codes)

            comb_dic = kpl_tool.handle_kpl_table_stocks()
            if len(comb_dic) != 0:
                comb_list = comb_dic[kpl_tool.CombID1]
                kpl_tool.delete_kpl_stock(kpl_tool.CombID1, comb_list)
            # 增加精选到开盘了
            kpl_tool.add_kpl_table_stocks(kpl_tool.CombID1, selected_stock_codes)
            top5_concepts = redis_tool.get_top5_concept()
            # 创建一个线程池
            with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
                future_to_thread = [executor.submit(task_handle_seleted_stock, stock, top5_concepts) for stock in
                                    sorted_selected_stocks]
                # 等待所有线程完成
                concurrent.futures.wait(future_to_thread)
        notice_tool.send_push_message('更新精选股票池成功')
        return {'code': 1, 'messge': res['msg'],
                'data': res['data']}
    elif res['code'] == 20001 or res['code'] == 20002:
        tld_tool.get_tld_token()
        return upadte_kpl_selected_stocks()
    else:
        notice_tool.send_push_message('更新精选股票池失败')
        return {'code': res['code'], 'messge': res['msg']}
# 精选任务
def task_handle_seleted_stock(stock, top5_concepts):
    with scheduler.app.app_context():
        topichots = []
        for concept in top5_concepts:
            if concept in stock['Topics']:
                topichots.append(concept)
        topichots_str = ','.join(topichots)
        stock['TopicsHot'] = topichots_str
        kpl_hots = kpl_tool.get_kpl_hots(stock['code'])
        if len(kpl_hots) > 0:
            kpl_hots_list = list(map(lambda x: x[1], kpl_hots))
            kpl_hots_str = ', '.join(kpl_hots_list)
            stock['kplTopics'] = kpl_hots_str
            # 更新数据库
            us = SeletedStockSchema(partial=True)
            selected_stock = us.load(stock)
            s_stock = SeletedStock.query.filter(SeletedStock.code == stock['code']).first()
            if s_stock:
                # 更新
                s_stock.CostLine15 = selected_stock.CostLine15
                s_stock.CostLine30 = selected_stock.CostLine30
                s_stock.Long = selected_stock.Long
                s_stock.Status = selected_stock.Status
                s_stock.Topics = selected_stock.Topics
                s_stock.code = selected_stock.code
                s_stock.ctime = selected_stock.ctime
                s_stock.date = selected_stock.date
                s_stock.id = selected_stock.id
                s_stock.intro = selected_stock.intro
                s_stock.name = selected_stock.name
                s_stock.score = selected_stock.score
                s_stock.snapshot = selected_stock.snapshot
                s_stock.tag = selected_stock.tag
                s_stock.utime = selected_stock.utime
                s_stock.kplTopics = selected_stock.kplTopics
                s_stock.TopicsHot = selected_stock.TopicsHot
                db.session.commit()

            else:
                db.session.add(selected_stock)
                db.session.commit()
        # kpl_tool.add_kpl_stock_notify(stock['code'], stock['CostLine30'])
        note = f'[精选]\n成本价1:  {stock["CostLine15"]:.2f}\n成本价2:  {stock["CostLine30"]:.2f}'
        kpl_tool.add_kpl_selected_stock_notes(stock['code'], note)

# 更新候选股票池
def upadte_kpl_candidate_stocks(date):

    token = redis_tool.get_tld_token()
    # 获取候选池
    res = tld_tool.get_tld_montior_stocks(token, date)
    if res['code'] == 200:
        candidate_stocks = res['data']['datas']
        print(candidate_stocks)

        if len(candidate_stocks) != 0:
            # 精选的codes
            last_date_time = datetime.strptime(date, '%Y-%m-%d')
            seleted_stocks = SeletedStock.query.filter(SeletedStock.date >= last_date_time).all()
            seleted_codes = list(map(lambda x: x.code, seleted_stocks))

            candidate_stocks_codes = list(map(lambda x: x['Code'], candidate_stocks))

            # # 清空候选池数据库
            # db.session.query(CandidateStock).delete()
            # db.session.commit()

            comb_dic = kpl_tool.handle_kpl_table_stocks()
            # 清空开盘啦中的候选股票池
            if len(comb_dic) != 0:
                comb_list = comb_dic[kpl_tool.CombID2]
                kpl_tool.delete_kpl_stock(kpl_tool.CombID2, comb_list)
            # 将股票添加到开盘啦app中
            kpl_tool.add_kpl_table_stocks(kpl_tool.CombID2, candidate_stocks_codes)
            candidate_stocks_codestr = ','.join(candidate_stocks_codes)
            # 修改redis
            redis_tool.set_candidate_codes(candidate_stocks_codestr)
            # 创建一个线程池
            with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
                future_to_thread = [executor.submit(task_handle_candidate_stock, stock, seleted_codes) for stock in
                                    candidate_stocks]
                # 等待所有线程完成
                concurrent.futures.wait(future_to_thread)
        notice_tool.send_push_message('更新候选股票池成功')
        return {'code': 1, 'messge': res['msg'],
                'data': res['data']}
    elif res['code'] == 20001 or res['code'] == 20002:
        tld_tool.get_tld_token()
        return upadte_kpl_candidate_stocks()
    else:
        return {'code': res['code'], 'messge': res['msg']}


# 候选任务
def task_handle_candidate_stock(stock, seleted_codes):
    with scheduler.app.app_context():
        # 获取在开盘啦中的概念
        kpl_hots = kpl_tool.get_kpl_hots(stock['Code'])
        if len(kpl_hots) > 0:
            kpl_hots_list = list(map(lambda x: x[1], kpl_hots))
            kpl_hots_str = ', '.join(kpl_hots_list)
            stock['kplTopics'] = kpl_hots_str
            stock['low'], stock['last_px'] = kpl_tool.get_low_data(stock['Code'])
            stock['isCover15'] = 0
            stock['isCover30'] = 0
            if stock['low'] < stock['NowCost15'] and stock['last_px'] > stock['NowCost15'] and stock['NowCost15'] > 0:
                stock['isCover15'] = 1
            if stock['low'] < stock['NowCost30'] and stock['last_px'] > stock['NowCost30'] and stock['NowCost30'] > 0:
                stock['isCover30'] = 1
            if stock['NowCost15'] == 0:
                stock['isCover15'] = 1
            if stock['NowCost30'] == 0:
                stock['isCover30'] = 1
            stock['cover15Time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            stock['cover30Time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            # 更新是否是精选股票
            if stock['Code'] in seleted_codes:
                stock['isSelected'] = 1
            us = CandidateStockSchema(partial=True)
            candidate_stock = us.load(stock)

            c_stock = CandidateStock.query.filter(CandidateStock.Code == stock['Code']).first()
            if c_stock is None:
                # 添加
                db.session.add(candidate_stock)
                db.session.commit()
            else:
                # 更新
               c_stock.ID = candidate_stock.ID
               c_stock.Code = candidate_stock.Code
               c_stock.CreateTime = candidate_stock.CreateTime
               c_stock.Date = candidate_stock.Date
               c_stock.Diff = candidate_stock.Diff
               c_stock.IsAv = candidate_stock.IsAv
               c_stock.Message = candidate_stock.Message
               c_stock.Name = candidate_stock.Name
               c_stock.NowCost15 = candidate_stock.NowCost15
               c_stock.NowCost30 = candidate_stock.NowCost30
               c_stock.Score = candidate_stock.Score
               c_stock.Status = candidate_stock.Status
               c_stock.Step = candidate_stock.Step
               c_stock.Topics = candidate_stock.Topics
               c_stock.TopicsHot = candidate_stock.TopicsHot
               c_stock.UpdateTime = candidate_stock.UpdateTime
               c_stock.kplTopics = candidate_stock.kplTopics
               c_stock.isSelected = candidate_stock.isSelected
               c_stock.IsWin = candidate_stock.IsWin
               c_stock.isCover15 = candidate_stock.isCover15
               c_stock.isCover30 = candidate_stock.isCover30
               c_stock.low = candidate_stock.low
               c_stock.last_px = candidate_stock.last_px
               c_stock.cover15Time = candidate_stock.cover15Time
               c_stock.cover30Time = candidate_stock.cover30Time
               db.session.commit()

        # # 添加通知
        # kpl_tool.add_kpl_stock_notify(stock['Code'], stock['NowCost30'])
        note = f'[候选]\n成本价1:  {stock["NowCost15"]:.2f}\n成本价2:  {stock["NowCost30"]:.2f}'
        # 添加笔记
        kpl_tool.add_kpl_candidate_stock_notes(stock['Code'], note)



# 更新开盘啦红黄预警股票
def upadte_kpl_red_yellow_stocks():
    token = redis_tool.get_tld_token()
    # 获取监控候选池
    res = tld_tool.get_tld_montior_info(token)
    if res['code'] == 200:
        montior_stocks = res['data']['datas']
        red_stocks = list(filter(lambda x: x['score'] > 1, montior_stocks))
        yellow_stocks = list(filter(lambda x: x['score'] == 0, montior_stocks))

        red_stocks_codes = list(map(lambda x: x['code'], red_stocks))
        yellow_stocks_codes = list(map(lambda x: x['code'], yellow_stocks))

        comb_dic = kpl_tool.handle_kpl_table_stocks()
        if len(comb_dic) != 0:
            comb_red_list = list(comb_dic[kpl_tool.RedCombID])
            kpl_tool.delete_kpl_stock(kpl_tool.RedCombID, comb_red_list)
            kpl_tool.add_kpl_table_stocks(kpl_tool.RedCombID, red_stocks_codes)

            comb_yellow_list = list(comb_dic[kpl_tool.YellowCombID])
            kpl_tool.delete_kpl_stock(kpl_tool.YellowCombID, comb_yellow_list)
            kpl_tool.add_kpl_table_stocks(kpl_tool.YellowCombID, yellow_stocks_codes)
        else:

            notice_tool.send_push_message('更新监控股票池失败')

        return {'code': 1, 'messge': res['msg'],
                'data': res['data']}
    elif res['code'] == 20001 or res['code'] == 20002:
        tld_tool.get_tld_token()
        return upadte_kpl_red_yellow_stocks()
    else:
        return {'code': res['code'], 'messge': res['msg']}

@kpl.route('/montior_stock_list')
def montior_stock_list():
    stocks = CandidateStock.query.all()
    def is_canmontior_stock(stock):
        if stock.isCover15 == 1 and stock.isCover30 == 1:
            return False
        return True
    stocks = list(filter(is_canmontior_stock, stocks))
    stocks_name = list(map(lambda x: x.Name, stocks))

    # 创建一个线程池
    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
        future_to_thread = [executor.submit(task_handle_montior_stock, stock) for stock in
                            stocks]
        # 等待所有线程完成
        concurrent.futures.wait(future_to_thread)
    return {'code': 1, 'messge': '成功'}

# 监控任务
def task_handle_montior_stock(stock):
    with scheduler.app.app_context():
        if stock.low <= 0:
            return
        data = kpl_tool.get_kpl_real_data(stock.Code)
        sq_stock = CandidateStock.query.filter_by(Code=stock.Code).first()
        if data['errcode'] == '0':
            last_px = data['real']['last_px']
            low_px = data['real']['low_px']
            sq_stock.last_px = last_px
            if stock.low > low_px and low_px > 0:
                sq_stock.low = low_px
            if sq_stock.NowCost15 >= 0 and sq_stock.isCover15 == 0 and sq_stock.low < sq_stock.NowCost15 and sq_stock.last_px > sq_stock.NowCost15:
                sq_stock.isCover15 = 1
                sq_stock.cover15Time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                content = '股票' + stock.Name + stock.Code + '突破盈亏比位置'
                notice_tool.send_push_copy_message(content, copy= stock.Code)
            if sq_stock.NowCost30 >= 0 and sq_stock.isCover30 == 0 and sq_stock.low < sq_stock.NowCost30 and sq_stock.last_px > sq_stock.NowCost30:
                sq_stock.isCover30 = 1
                sq_stock.cover30Time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                content = '股票' + sq_stock.Name + sq_stock.Code + '突破成本线位置'
                notice_tool.send_push_copy_message(content, copy= stock.Code)
            db.session.commit()

@kpl.route('/user')
def set_user():
    print('===')
    user = {'id': 10011, 'name': 'liuxiang', 'sex': '0',
            'time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
    us = UserSchema(partial=True)
    user_sql = us.load(user)

    db.session.add(user_sql)
    db.session.commit()
    return '成功'


@kpl.route('/updatetradingcalendar')
def updatetradingcalendar():
    res = ak.tool_trade_date_hist_sina()
    json = res.to_json(orient='records')
    TradingCalendar.query.delete()
    trade_dates = []
    for index, row in res.iterrows():
        trade_date = TradingCalendar()
        trade_date.id = index
        trade_date.trade_date = row['trade_date']
        trade_dates.append(trade_date)
    db.session.bulk_save_objects(trade_dates)
    db.session.commit()
    return {'code': 1, 'messge': '更新成功', 'data': json}

@kpl.route('/gettradingcalendar')
def gettradingcalendar():
    date = TradingCalendar.query.filter(TradingCalendar.trade_date < datetime.now()).order_by(desc(TradingCalendar.trade_date)).limit(5).all()
    ts = TradingCalendarSchema(many=True)
    data = ts.dump(date)
    dates = ','.join(list(map(lambda x: x['trade_date'], data)))
    redis_tool.set_lx_last_trade_date(dates)
    return {'code': 1, 'messge': '获取成功', 'data': dates}

@kpl.route('/updateHots')
def update_hots():
    dates = redis_tool.get_lx_last_trade_date()
    hots = kpl_tool.gethots(dates)
    if len(hots) == 0:
        return {'code': 0, 'messge': '获取失败'}
    else:
        redis_tool.set_lx_kpl_hot_concepts(','.join(hots))
        return {'code': 1, 'messge': '获取成功', 'data': ','.join(hots)}

@kpl.route('/getstockconcepts/<code>')
def getstockconcepts(code):
    if len(code) == 0:
        return {'code': 0, 'messge': f'请输入股票代码',
                'data': {}}
    kpl_hots = kpl_tool.get_kpl_hots(code)
    kpl_hots_str = ','.join(list(map(lambda x: x[1], kpl_hots)))
    if len(kpl_hots) == 0:
        return {'code': 0, 'messge': f'获取股票概念失败',
                'data': {}}

    return {'code': 1, 'messge': f'获取股票概念成功',
                'data': {
                    'kpl_concept': kpl_hots_str,
                    'kpl_hot_concept': redis_tool.get_lx_kpl_hot_concepts()
                }}


